package com.zm.schedule.schedulemgr.service.impl;

import java.net.InetAddress;
import java.util.List;

import javax.annotation.Resource;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.JobListener;
import org.quartz.Scheduler;
import org.quartz.Trigger.TriggerState;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.stereotype.Service;

import com.zm.base.core.exception.BaseException;
import com.zm.schedule.schedulemgr.po.TbZmScheduleJob;
import com.zm.schedule.schedulemgr.service.IScheduleService;
import com.zm.schedule.schedulemgr.service.ISchedulerBuilder;
import com.zm.schedule.schedulemgr.util.ClazzUtil;

/**
 * @author chenhuaming
 * @Time：2017年5月2日 下午5:47:47
 * @version 1.0
 */
@Service("schedulerBuilder")
public class SchedulerBuilder implements ISchedulerBuilder {
	private static Scheduler scheduler;
	@Resource(name="scheduleService")
	private IScheduleService scheduleService;
	@Resource(name="ZMJobCountListener")
	private JobListener jobListener;
	public void createScheduler(List<TbZmScheduleJob> jobList) throws BaseException,Exception{
		scheduler = new StdSchedulerFactory().getScheduler();
		scheduler.getListenerManager().addJobListener(jobListener);
		for (TbZmScheduleJob job : jobList) {
			//获取本机ip
			InetAddress addr = InetAddress.getLocalHost();
			String ip=addr.getHostAddress();//获得本机IP(配置ip的情况)
			if(!"".equals(job.getIp())){
				if(!ip.equals(job.getIp().trim())){
					continue;
				}
			}
			//停止的任务
			if("1".equals(job.getStatus())){
				continue;
			}
			
		    TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
		    //获取trigger，即在spring配置文件中定义的 bean id="myTrigger"
		    CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
		    //不存在，创建一个
		    if (null == trigger) {
		        JobDetail jobDetail = JobBuilder.newJob(ClazzUtil.getClazz(job.getClassName()))
		            .withIdentity(job.getJobName(), job.getJobGroup()).build();
		        jobDetail.getJobDataMap().put("scheduleJob", job);
		        //表达式调度构建器
		        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job
		            .getCronExpression());
		        //按新的cronExpression表达式构建一个新的trigger
		        trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup()).withSchedule(scheduleBuilder).build();
		        scheduler.scheduleJob(jobDetail, trigger);
		        scheduler.start();
		    } else {
		        // Trigger已存在，那么更新相应的定时设置
		        //表达式调度构建器
		        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job
		            .getCronExpression());

		        //按新的cronExpression表达式重新构建trigger
		        trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
		            .withSchedule(scheduleBuilder).build();
		        //按新的trigger重新设置job执行
		        scheduler.rescheduleJob(triggerKey, trigger);
		    }
		}
	}
	/**
	 * 初始化任务
	 * @author chenhuaming
	 * @Time 2017年5月10日
	 * @throws BaseException
	 * @throws Exception
	 */
	public void initSchedule() throws BaseException, Exception{
		List<TbZmScheduleJob> schedules=scheduleService.getAllTbZmScheduleJob();
		if(null!=schedules&&!"".equals(schedules)){
			createScheduler(schedules);
		}else{
			throw new BaseException();
		}
	}
	
	/**
	 * 新增一个任务
	 * addCronTriggerJob:() 
	 * @author chenhuaming 
	 * @param job
	 * @throws Exception 
	 * @throws BaseException 
	 */
	public  void addCronTriggerJob(TbZmScheduleJob job) throws BaseException, Exception{
		//添加数据库数据
		//scheduleService.saveSchedule(job);
		//设置任务，并开启定时器
		 TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
		    //获取trigger，即在spring配置文件中定义的 bean id="myTrigger"
		 CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
		 JobDetail jobDetail = JobBuilder.newJob(ClazzUtil.getClazz(job.getClassName()))
		            .withIdentity(job.getJobName(), job.getJobGroup()).build();
        jobDetail.getJobDataMap().put("scheduleJob", job);
        //表达式调度构建器
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job
            .getCronExpression());
        //按新的cronExpression表达式构建一个新的trigger
        trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup()).withSchedule(scheduleBuilder).build();
        scheduler.scheduleJob(jobDetail, trigger);
        scheduler.start();
	}
	
	/**
	 * 立即开启任务
	 */
	public void startJob(TbZmScheduleJob scheduleJob)throws BaseException,Exception{
		JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
		scheduler.triggerJob(jobKey);
	}
	/**
	 * 暂停任务
	 */
	public void pauseJob(TbZmScheduleJob scheduleJob)throws BaseException,Exception{
		JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
		scheduler.pauseJob(jobKey);
		getTriggerStatusByJobName(scheduleJob);
	}
	/**
	 * 恢复任务
	 */
	public void recoverJob(TbZmScheduleJob scheduleJob)throws BaseException,Exception{
		JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
		scheduler.resumeJob(jobKey);
	}
	/**
	 * 删除任务
	 */
	public void delJob(TbZmScheduleJob scheduleJob)throws BaseException,Exception{
		JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
		scheduler.deleteJob(jobKey);
	}
	/**
	 * 修改任务
	 * upateJob:() 
	 * @author chenhuaming 
	 * @param scheduleJob
	 * @throws BaseException
	 * @throws Exception
	 */
	public void upateJob(TbZmScheduleJob scheduleJob)throws BaseException,Exception{
		JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
		scheduler.deleteJob(jobKey);
		addCronTriggerJob(scheduleJob);
	}
	/**
	 * 获取韧度调度的状态
	 * getTriggerStatusByJobName:() 
	 * @author chenhuaming 
	 * @param jobName
	 * @return
	 * @throws SchedulerException
	 */
	public String getTriggerStatusByJobName(TbZmScheduleJob scheduleJob)
		    throws BaseException,Exception
	  {
		TriggerKey triggerKey=TriggerKey.triggerKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
		TriggerState triggerState=scheduler.getTriggerState(triggerKey);
		return triggerState.name();
	  }
	@Override
	public void stopJob(TbZmScheduleJob scheduleJob) throws BaseException,
			Exception {
		delJob(scheduleJob);
	}
}
